package com.lzb.play.fragment;

import static android.app.Activity.RESULT_OK;

import android.Manifest;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.PermissionUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.UriUtils;
import com.blankj.utilcode.util.UtilsTransActivity;
import com.blankj.utilcode.util.VolumeUtils;
import com.lzb.play.BaseNoModelFragment;
import com.lzb.play.Content;
import com.lzb.play.R;
import com.lzb.play.activity.GridSettingActivity;
import com.lzb.play.activity.PianoSettingActivity;
import com.lzb.play.basic.media.AudioPlayerImpl;
import com.lzb.play.basic.utils.FileUtil;
import com.lzb.play.bean.PianoKeyBean;
import com.lzb.play.databinding.FragmentPianoPlayBinding;
import com.lzb.play.dialog.PermissionExplainDialog;
import com.lzb.play.dialog.RecordSaveDialog;
import com.lzb.play.utils.AppSpUtils;
import com.lzb.play.utils.MyAudioPlayerImpl;
import com.lzb.play.utils.MyMediaRecorder;
import com.lzb.play.view.PianoKeyboardView;

import java.util.ArrayList;
import java.util.List;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link PianoPlayFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class PianoPlayFragment extends BaseNoModelFragment<FragmentPianoPlayBinding> implements View.OnClickListener {

    private int max, min, now, progress;
    private List<PianoKeyBean> listShow = new ArrayList<>();
    private boolean isSetting, isPlay, isRecord;
    private MyAudioPlayerImpl mAudioPlayer;
    private MyMediaRecorder mRecorder;
    private Handler mHandler;
    private Runnable playRunnable = new Runnable() {
        int[] beat = new int[]{0, 1, 0, 1, 2, 2, 3, 3, 4, 5, 5, 4, 6, 6};
        private int pos = 0;

        @Override
        public void run() {
            if (!isPlay) {
                mAudioPlayer.pause();
                mHandler.removeCallbacks(this);
                return;
            }

            boolean isPressed = listShow.get(beat[pos]).isSetting();

            if (isPressed) {
                int keyIndex = beat[pos];

                // 按下按键
                mDataBinding.pianoView.setWhiteKeyPressed(keyIndex, true);

                // 播放音频
                Uri uri = Uri.parse("android.resource://" + AppUtils.getAppPackageName() + "/" + listShow.get(keyIndex).getRawId());
                mAudioPlayer.play(UriUtils.uri2File(uri).getPath());

                // 设置抬起时机
                mHandler.postDelayed(() -> {
                    mDataBinding.pianoView.setWhiteKeyPressed(keyIndex, false);
                }, 400);
            }

            pos = (pos + 1) % 14;
            if (isPressed) {
                mHandler.postDelayed(this, 500);
            } else {
                mHandler.post(this);
            }
        }
    };

    @Override
    protected int onCreate() {
        return R.layout.fragment_piano_play;
    }

    @Override
    protected void initView() {
        mDataBinding.ivSetting.setOnClickListener(this);
        mDataBinding.llPlay.setOnClickListener(this);
        mDataBinding.ivRecord.setOnClickListener(this);

        mAudioPlayer = new MyAudioPlayerImpl();
        mRecorder = new MyMediaRecorder();
        mHandler = new Handler();

        mAudioPlayer.setHasLoop(false);

        max = VolumeUtils.getMaxVolume(AudioManager.STREAM_MUSIC);
        min = VolumeUtils.getMinVolume(AudioManager.STREAM_MUSIC);
        now = VolumeUtils.getVolume(AudioManager.STREAM_MUSIC);
        progress = now * 100 / (max - min);
        mDataBinding.tvVolume.setText(progress + getContext().getString(R.string.unit_percent));
        mDataBinding.sbProgress.setProgress(progress);
        mDataBinding.sbProgress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                progress = i;
                setVolume();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        mDataBinding.pianoView.setOnPianoKeyListener(new PianoKeyboardView.OnPianoKeyListener() {
            @Override
            public void onWhiteKeyPressed(int keyIndex) {
                if (!isPlay) {
                    if (listShow.get(keyIndex).isSetting()) {
                        mDataBinding.pianoView.setWhiteKeyPressed(keyIndex, true);
                        Uri uri = Uri.parse("android.resource://" + AppUtils.getAppPackageName() + "/" + listShow.get(keyIndex).getRawId());
                        mAudioPlayer.play(UriUtils.uri2File(uri).getPath());
                    } else {
                        ToastUtils.showShort(getString(R.string.please_set_bird));
                    }
                }
            }

            @Override
            public void onWhiteKeyReleased(int keyIndex) {
                mDataBinding.pianoView.setWhiteKeyPressed(keyIndex, false);
//                mAudioPlayer.pause();
            }

            @Override
            public void onBlackKeyPressed(int keyIndex) {

            }

            @Override
            public void onBlackKeyReleased(int keyIndex) {

            }
        });
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (id == R.id.ivSetting) {//设置
            Intent intent = new Intent(getActivity(), PianoSettingActivity.class);
            startActivityForResult(intent, 1002);
        } else if (id == R.id.llPlay) {//自动演奏
            if (isSetting) {
                isPlay = !isPlay;
                mDataBinding.ivPlay.setImageResource(isPlay ? R.drawable.icon_stop : R.drawable.icon_play);
                mDataBinding.tvPlay.setText(isPlay ? getString(R.string.stop_play) : getString(R.string.auto_play));
                if (isPlay) {
                    play();
                } else {
                    mAudioPlayer.pause();
                }
            } else {
                ToastUtils.showShort(getString(R.string.please_set_bird));
            }
        } else if (id == R.id.ivRecord) {//录音
            if (!isRecord) {
                getPermission();
            } else {
                isRecord = false;
                mRecorder.stopRecording();
                showRecordSaveDialog();
            }
            mDataBinding.ivRecord.setImageResource(isRecord ? R.drawable.icon_record_select : R.drawable.icon_record_no);
        }
    }

    @Override
    protected void initData() {
        getData();
    }

    private void play() {
        mHandler.post(playRunnable);
    }

    private void getData() {
        listShow.clear();
        List<PianoKeyBean> listSp = AppSpUtils.getPianoKeyList();
        if (listSp != null && listSp.size() > 0) {
            listShow.addAll(listSp);
        } else {
            listSp = new ArrayList<>();
            listSp.add(new PianoKeyBean(0, 0, false));
            listSp.add(new PianoKeyBean(1, 0, false));
            listSp.add(new PianoKeyBean(2, 0, false));
            listSp.add(new PianoKeyBean(3, 0, false));
            listSp.add(new PianoKeyBean(4, 0, false));
            listSp.add(new PianoKeyBean(5, 0, false));
            listSp.add(new PianoKeyBean(6, 0, false));
            AppSpUtils.savePianoKeyList(listSp);
            listShow.addAll(listSp);
        }
        for (int i = 0; i < listShow.size(); i++) {
            if (listShow.get(i).isSetting()) isSetting = true;
        }
    }

    private void getPermission() {
        PermissionExplainDialog dialog = new PermissionExplainDialog(mContext);
        dialog.setContent(getString(R.string.get_record_permission));
        PermissionUtils.permission(Manifest.permission.RECORD_AUDIO).explain(new PermissionUtils.OnExplainListener() {
            @Override
            public void explain(@NonNull UtilsTransActivity activity, @NonNull List<String> denied, @NonNull ShouldRequest shouldRequest) {
                dialog.show();
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        shouldRequest.start(true);
                    }
                }, 500);
            }
        }).callback(new PermissionUtils.SimpleCallback() {
            @Override
            public void onGranted() {
                dialog.dismiss();
                startRecord();
            }

            @Override
            public void onDenied() {
                dialog.dismiss();
            }
        }).request();
    }

    //开始录音
    private void startRecord() {
        String musicPath = FileUtil.generateFilePath(Content.Temp, ".mp3");
        try {
            isRecord = true;
            mRecorder.setMyRecAudioFile(FileUtils.getFileByPath(musicPath));
            if (!mRecorder.startRecorder()) {
                isRecord = false;
                ToastUtils.showShort(R.string.audio_fail_tips);
            }
        } catch (Exception e) {
            isRecord = false;
            ToastUtils.showShort(R.string.audio_fail_tips2);
            e.printStackTrace();
        }
        mDataBinding.ivRecord.setImageResource(isRecord ? R.drawable.icon_record_select : R.drawable.icon_record_no);
    }

    private void showRecordSaveDialog() {
        RecordSaveDialog dialog = new RecordSaveDialog(mContext);
        dialog.setAudioPath(mRecorder.getMyRecAudioFile().getPath());
        dialog.show();
    }

    private void setVolume() {
        mDataBinding.tvVolume.setText(progress + getContext().getString(R.string.unit_percent));
        float value = calSeekBarRealValue(mDataBinding.sbProgress, progress);
        VolumeUtils.setVolume(AudioManager.STREAM_MUSIC, (int) value, 0);
    }

    private float calSeekBarRealValue(SeekBar seekBar, int progress) {
        int progressRange = seekBar.getMax();
        float value = progress * 1.0f / progressRange * (max - min) + min;
        return value;
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mAudioPlayer != null) {
            mAudioPlayer.pause();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        if (isPlay) isPlay = false;
        mDataBinding.ivPlay.setImageResource(isPlay ? R.drawable.icon_stop : R.drawable.icon_play);
        mDataBinding.tvPlay.setText(isPlay ? getString(R.string.stop_play) : getString(R.string.auto_play));
        mHandler.removeCallbacks(playRunnable);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mAudioPlayer != null) {
            mAudioPlayer.stop();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1002 && resultCode == RESULT_OK && data != null) {
            getData();
        }
    }

}